﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using DCRF.Common.Interface;
using DCRF.Common.Primitive;
using System.IO;
using System.Collections;
using DCRF.Common.Connection;
using System.Threading;

namespace DCRF.BaseComponents.Commander
{
    public partial class CmdForm : UserControl
    {
        private IBlockWeb myWeb = null;
        private Dictionary<TabPage, Guid> ids = new Dictionary<TabPage, Guid>();
        private int lastCount = 0;
        private Hashtable globalState = new Hashtable();
        private Guid watchId = Guid.Empty;
        private bool scheduleOn = false;

        public CmdForm()
        {
            InitializeComponent();
        }

        public void Start(IBlockWeb web)
        {
            myWeb = web;

            NewQuickWatchTab();
            NewTreeTab();

            //add empty code tab
            NewCodeTab();            
        }

        #region New Tab

        private void NewTreeTab()
        {
            TabPage tp = addTab("BlockTree");

            int tabIndex = tabControl1.TabPages.Count - 1;

            Guid treeId = myWeb.AddBlock(CID.New("BlockTreeBlock"));

            myWeb[treeId]["Container"].AttachEndPoint(tp);
            //myWeb[treeId]["AddToGlobalState"].AttachEndPoint(watchId, "AddObject");
            myWeb[treeId].ProcessRequest("BindToUI");

            globalState.Add("ROOTWEB", myWeb[treeId].ProcessRequest("GetInnerWeb"));
            myWeb[watchId].ProcessRequest("Refresh");

            ids.Add(tp, treeId);
        }

        private void NewQuickWatchTab()
        {
            TabPage tp = addTab("QuickWatch");

            int tabIndex = tabControl1.TabPages.Count - 1;

            Guid qw = myWeb.AddBlock(CID.New("QuickWatchBlock"));

            myWeb[qw]["Container"].AttachEndPoint(tp);
            myWeb[qw]["GlobalState"].AttachEndPoint(globalState);
            myWeb[qw].ProcessRequest("BindToUI");

            ids.Add(tp, qw);

            watchId = qw;
        }

        private void NewCodeTab()
        {
            TabPage tab = addTab(null);

            Guid id = myWeb.AddBlock(new CID("DCRFCommandBox", new BlockVersion(0, 1, 0, 0)));

            myWeb[id]["Container"].AttachEndPoint(tab);
            myWeb[id]["GlobalState"].AttachEndPoint(globalState);
            myWeb[id].ProcessRequest("Start");

            ids.Add(tab, id);
        }

        private TabPage addTab(string name)
        {

            string title = name;

            if (title == null)
            {
                lastCount++;

                title = "tab" + lastCount;
            }

            TabPage tp = new TabPage(title);

            tabControl1.TabPages.Add(tp);

            return tp;
        }


        #endregion

        private void refreshToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Guid id = ids[tabControl1.SelectedTab];

            myWeb[id].ProcessRequest("Refresh");
        }


        #region Code Tab Context Menu Commands

        private void newCodeTabToolStripMenuItem_Click(object sender, EventArgs e)
        {
            NewCodeTab();
        }

        private void loadScriptToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();

            ofd.DefaultExt = ".cmdbox";

            if (ofd.ShowDialog() == DialogResult.OK)
            {
                string data = File.ReadAllText(ofd.FileName);

                Guid id = ids[tabControl1.SelectedTab];
                myWeb[id].ProcessRequest("SetInput", data);

                MessageBox.Show("Load Done!");
            }
        }

        private void saveScriptToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.DefaultExt = ".cmdbox";

            if (sfd.ShowDialog() == DialogResult.OK)
            {
                Guid id = ids[tabControl1.SelectedTab];

                string input = (string)myWeb[id].ProcessRequest("GetInput");

                StreamWriter sw = new StreamWriter(sfd.FileName);
                sw.Write(input);
                sw.Close();

                MessageBox.Show("Save Done!");
            }
        }

        private void executeScriptToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //call execute service of the active block
            Guid id = ids[tabControl1.SelectedTab];

            myWeb[id].ProcessRequest("Execute");
        }

        private void previousScriptToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            Guid id = ids[tabControl1.SelectedTab];

            myWeb[id].ProcessRequest("HistoryPrevious");
        }

        private void nextScriptToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            Guid id = ids[tabControl1.SelectedTab];

            myWeb[id].ProcessRequest("HistoryNext");
        }

        private void clearHistoryToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            Guid id = ids[tabControl1.SelectedTab];

            myWeb[id].ProcessRequest("ClearHistory");
        }


        private void closeTabToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (tabControl1.TabPages.Count == 3) return;

            TabPage tp = tabControl1.SelectedTab;
            Guid ig = ids[tp];

            ids.Remove(tp);

            tabControl1.TabPages.Remove(tp);

            myWeb.DeleteBlock(ig);
        }
        #endregion

        private void tabControl1_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Right)
            {
                if (tabControl1.GetTabRect(tabControl1.SelectedIndex).Contains(e.Location))
                {
                    Guid activeId = ids[tabControl1.SelectedTab];

                    if (myWeb.GetBlockId(activeId).Identifier == "DCRFCommandBox")
                    {
                        toolstripTabTitle.Text = tabControl1.SelectedTab.Text;
                        codeTabContextMenu.Show(tabControl1, e.Location);
                    }
                    else if (myWeb.GetBlockId(activeId).Identifier == "QuickWatchBlock")
                    {
                        watchContextMenu.Show(tabControl1, e.Location);
                    }
                }
            }
        }

        private void resetWatchToolStripMenuItem_Click(object sender, EventArgs e)
        {
            TabPage tp = tabControl1.SelectedTab;
            Guid ig = ids[tp];

            object temp = globalState["ROOTWEB"];
            globalState.Clear();
            globalState.Add("ROOTWEB", temp);

            myWeb[ig].ProcessRequest("Refresh");
        }

        private void CmdForm_KeyDown(object sender, KeyEventArgs e)
        {
        }

        private void CmdForm_KeyUp(object sender, KeyEventArgs e)
        {
            Guid activeId = ids[tabControl1.SelectedTab];

            if (myWeb.GetBlockId(activeId).Identifier == "DCRFCommandBox")
            {
                foreach (ToolStripItem item in codeTabContextMenu.Items)
                {
                    if (item is ToolStripMenuItem)
                    {
                        if (e.KeyData == (item as ToolStripMenuItem).ShortcutKeys)
                        {
                            item.PerformClick();
                        }
                    }
                }
            }
        }

        private void CmdForm_Load(object sender, EventArgs e)
        {
            tabControl1.KeyUp += new KeyEventHandler(tabControl1_KeyUp);
        }

        void tabControl1_KeyUp(object sender, KeyEventArgs e)
        {
            CmdForm_KeyUp(sender, e);
        }

        private void toolstripTabTitle_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == 13)
            {
                //rename active tab
                tabControl1.SelectedTab.Text = toolstripTabTitle.Text;
                codeTabContextMenu.Hide();
            }
        }

        private void autoExecuteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (autoExecuteToolStripMenuItem.Text.StartsWith("Stop"))
            {
                scheduleOn = false;
            }
            else
            {
                //call execute service of the active block
                Guid id = ids[tabControl1.SelectedTab];
                scheduleOn = true;

                ThreadPool.QueueUserWorkItem(new WaitCallback(delegate(object arg)
                    {
                        while (scheduleOn)
                        {
                            myWeb[id].ProcessRequest("Execute", true);
                            Thread.Sleep(5000);
                        }

                        autoExecuteToolStripMenuItem.Text = "Auto Execute";
                    }));

                autoExecuteToolStripMenuItem.Text = "Stop Execute Schedule";
            }
        }

    }
}
